package com.gitee.deeround.javaprotect.tool;

import com.gitee.deeround.javaprotect.tool.util.CommonUtils;
import com.gitee.deeround.javaprotect.tool.util.HexUtil;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;

public class Encrypt implements IEncrypt {
    private static final String ALGORITHM = "AES";
    private static final String AES_ECB_PADDING = "AES/ECB/PKCS5Padding";
    private Cipher cipher;

    public Encrypt() {
        try {
            //获取SecretKey对象,也可以使用getSecretKey()方法
            SecretKey secretKey = new SecretKeySpec(Context.Instance.getPassword().getBytes(StandardCharsets.UTF_8), ALGORITHM);
            //获取指定转换的密码对象Cipher（参数：算法/工作模式/填充模式）
            cipher = Cipher.getInstance(AES_ECB_PADDING);
            //用密钥和一组算法参数规范初始化此Cipher对象（加密模式）
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        } catch (Exception e) {
            throw new ProtectException(e);
        }
    }

    @Override
    public String eKey() {
        byte[] bytes = e(getAgentKeyPlaintext().getBytes(StandardCharsets.UTF_8), "D25C85E7EB9D077E".getBytes(StandardCharsets.UTF_8));
        return HexUtil.encodeHex(bytes);
    }

    @Override
    public String eClassName(String className) {
        return CommonUtils.getMD5(className);
    }

    @Override
    public byte[] e(byte[] d) {
        try {
            //执行加密操作
            return cipher.doFinal(d);
        } catch (Exception e) {
            throw new ProtectException(e);
        }
    }

    private byte[] e(byte[] d, byte[] k) {
        try {
            //获取SecretKey对象,也可以使用getSecretKey()方法
            SecretKey secretKey = new SecretKeySpec(k, ALGORITHM);
            //获取指定转换的密码对象Cipher（参数：算法/工作模式/填充模式）
            Cipher cipher1 = Cipher.getInstance(AES_ECB_PADDING);
            //用密钥和一组算法参数规范初始化此Cipher对象（加密模式）
            cipher1.init(Cipher.ENCRYPT_MODE, secretKey);
            //执行加密操作
            return cipher1.doFinal(d);
        } catch (Exception e) {
            throw new ProtectException(e);
        }
    }

    private String getAgentKeyPlaintext() {
        String md5 = CommonUtils.getMD5(System.currentTimeMillis() + "");
        String content = Context.Instance.getPassword();

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 32; i++) {
            sb.append(md5.charAt(i)).append(content.charAt(i));
        }

        sb.append(new SecureRandom().nextInt(9));

        return sb.toString();
    }
}
